#ifndef __SL_PORT__H
#define __SL_PORT__H


#include "iodefine.h"
#include "sl_types.h"


// I/O pin mode (function) for CR register
#define PIN_MODE_ERROR			-1		// illegal pin indication
#define PIN_MODE_IO				0		// general input/output, PA PB PD PE
#define PIN_MODE_OTHER			1		// no I/O, PA PB PD PE

// I/O pin 11 mode (function) of port B for CR register, CPU operation mode 2
#define PIN_B11_MODE_A21		1		// address output (A21)
#define PIN_B11_MODE_POD		2		// POD_ output, disable input

// I/O pin mode (function) of port C for CR register, CPU operation mode 2
#define PIN_C6_MODE_CS2			1		// chip select output (CS2_)
#define PIN_C6_MODE_IRQ6		2		// interrupt request input (IRQ6_)
#define PIN_C6_MODE_ADEND		3		// A/D conversion end output (ADEND)
#define PIN_C11_MODE_TOE10		1		// ATU one-shot pulse output (TOE10)
#define PIN_C11_MODE_DRAK0		2		// DMAC DREQ0_ acceptance signal output (DRAK0)
#define PIN_C12_MODE_TOF10		1		// ATU one-shot pulse output (TOF10)
#define PIN_C12_MODE_DRAK1		2		// DMAC DREQ1_ acceptance signal output (DRAK1)

// I/O pin mode (function) of port F for CR register, CPU operation mode 0,1,2
#define PIN_F11_MODE_BREQ		1		// bus request input (BREQ_)
#define PIN_F11_MODE_PULS7		2		// APC pulse output (PULS7)
#define PIN_F10_MODE_BACK		1		// bus request acknowledge output (BACK_)
#define PIN_F10_MODE_PULS6		2		// APC pulse output (PULS6)
#define PIN_F9_MODE_CS3			1		// chip select output (CS3_)
#define PIN_F9_MODE_IRQ7		2		// interrupt request input (IRQ7_)
#define PIN_F9_MODE_PULS5		3		// APC pulse output (PULS5)
#define PIN_F8_MODE_SCK2		1		// serial clock input/output (SCK2)
#define PIN_F8_MODE_PULS4		2		// APC pulse output (PULS4)
#define PIN_F7_MODE_DREQ0		1		// DMA transfer request input (DREQ0_)
#define PIN_F7_MODE_PULS3		2		// APC pulse output (PULS3)
#define PIN_F6_MODE_DACK0		1		// DMA transfer acceptance output (DACK0)
#define PIN_F6_MODE_PULS2		2		// APC pulse output (PULS2)
#define PIN_F5_MODE_DREQ1		1		// DMA transfer request input (DREQ1_)
#define PIN_F5_MODE_PULS1		2		// APC pulse output (PULS1)
#define PIN_F4_MODE_DACK1		1		// DMA transfer acceptance output (DACK1)
#define PIN_F4_MODE_PULS0		2		// APC pulse output (PULS0)

// I/O pin mode (function) of port G for CR register, all CPU operation mode
#define PIN_G15_MODE_IRQ5		1		// interrupt request input (IRQ5_)
#define PIN_G15_MODE_TIOB5		2		// ATU input capture I/O compare outpot (TIOB5)
#define PIN_G14_MODE_IRQ4		1		// interrupt request input (IRQ4_)
#define PIN_G14_MODE_TIOA5		2		// ATU input capture I/O compare outpot (TIOA5)
#define PIN_G0_MODE_ADTRG		1		// A/D conversion trigger input (ADTRG_)
#define PIN_G0_MODE_IRQOUT		2		// interrupt request outpot (IRQOUT_)

// pin 159 (IRQOUT_) mode (function) of port G for CR register
#define PIN_159_MODE_HIGH		0		// always high
#define PIN_159_MODE_IRQOUT		1		// output IRQOUT_


typedef struct st_port_t
{
	WORD DR;
	WORD IOR;
	union
	{
		WORD CR;
		WORD CR1;
	}_cr;
	WORD CR2;
}st_port;

// I/O direction for IOR register
typedef enum
{
	IOD_INPUT = 0,
	IOD_OUTPUT = 1
} IODirection;


////////////////////////////////////////////////////////////////////////////////

WORD sl_port_inputPortData(volatile st_port* port);
void sl_port_outputPortData(volatile st_port *port, WORD data);
WORD sl_port_getOutPortputData(volatile st_port *port);
LEVEL InputPinData(volatile st_port *port, BYTE pin);

void sl_port_outputPinData(volatile st_port *port, BYTE pin, LEVEL data);
LEVEL sl_port_getOutputPinData(volatile st_port *port, BYTE pin);
WORD sl_port_getPortDirection(volatile st_port *port) ;
void sl_port_setPortDirection(volatile st_port *port, WORD direction);
IODirection sl_port_getPinDirection(volatile st_port *port, BYTE pin);
void sl_port_setPinDirection(volatile st_port *port, BYTE pin, IODirection direction);
void sl_port_setPortDR(volatile st_port *port, WORD direction);
WORD sl_port_getPortMode(volatile st_port *port);
WORD sl_port_getPortMode1(volatile st_port *port);
WORD sl_port_getPortMode2(volatile st_port *port);
void sl_port_setPortMode(volatile st_port *port, WORD mode);
void sl_port_setPortMode1(volatile st_port *port, WORD mode);
void sl_port_setPortMode2(volatile st_port* port, WORD mode);

int sl_port_getPinMode(volatile st_port *port, BYTE pin);
void sl_port_setPinMode(volatile st_port *port, BYTE pin, int mode);

LEVEL sl_port_inputPinData(volatile st_port *port,unsigned char pin);

st_port * sl_port_getPortA(void);
int sl_portA_getPinMode(volatile st_port *port, BYTE pin);
void sl_portA_setPinMode(volatile st_port *port, BYTE pin, int mode);


////////////////////////////////////////////////////////////////////////////////
// class CPortB
st_port * sl_port_getPortB();
// override member function
LEVEL sl_portB_inputPinData(volatile st_port *port, BYTE pin);

LEVEL sl_portB_outputPinData(volatile st_port *port, BYTE pin, LEVEL data);

LEVEL sl_portB_getOutputPinData(volatile st_port *port, BYTE pin);
IODirection sl_portB_getPinDirection(volatile st_port *port, BYTE pin);
void sl_portB_setPinDirection(volatile st_port *port, BYTE pin, IODirection direction);

int sl_portB_getPinMode(volatile st_port *port, BYTE pin);
void sl_portB_setPinMode(volatile st_port *port, BYTE pin, int mode);



////////////////////////////////////////////////////////////////////////////////
// class CPortC
st_port * sl_port_getPortC();
int sl_portC_getPinMode(volatile st_port *port, BYTE pin);
void sl_portC_setPinMode(volatile st_port *port, BYTE pin, int mode);



////////////////////////////////////////////////////////////////////////////////
// class CPortD
st_port * sl_port_getPortD();
int sl_portD_getPinMode(volatile st_port *port, BYTE pin);
void sl_portD_setPinMode(volatile st_port *port, BYTE pin, int mode);


////////////////////////////////////////////////////////////////////////////////
// class CPortE
st_port * sl_port_getPortE();
int sl_portE_getPinMode(volatile st_port *port, BYTE pin);
void sl_portE_setPinMode(volatile st_port *port, BYTE pin, int mode);



////////////////////////////////////////////////////////////////////////////////
// class CPortF
st_port * sl_port_getPortF();
int sl_portF_getPinMode(volatile st_port *port, BYTE pin);
void sl_portF_setPinMode(volatile st_port *port, BYTE pin, int mode);


////////////////////////////////////////////////////////////////////////////////
// class CPortG
st_port * sl_port_getPortG();
WORD sl_portG_GetPinMode(volatile st_port *port, BYTE pin);
void sl_portG_setPinMode(volatile st_port *port, BYTE pin, int mode);

// pin mode (function) of CPU pin 159 (IRQOUT_ output)
int sl_portG_setPin159ModeFor(volatile st_port *port);
void sl_portG_setPin159Mode(volatile st_port *port, int mode);


////////////////////////////////////////////////////////////////////////////////
// class CPortH
st_port * sl_port_getPortH();
void sl_portH_outputPortData(volatile st_port *port, WORD data);
WORD sl_portH_getOutPortputData(volatile st_port *port);
void sl_portH_outputPinData(volatile st_port *port, BYTE pin, LEVEL data);
LEVEL sl_portH_getOutputPinData(volatile st_port *port, BYTE pin);
WORD sl_portH_getPortDirection(volatile st_port *port);
void sl_portH_setPortDirection(volatile st_port *port, WORD direction);
IODirection sl_portH_getPinDirection(volatile st_port *port, BYTE pin);
void sl_portH_setPinDirection(volatile st_port *port, BYTE pin, IODirection direction);
WORD sl_portH_getPortMode(volatile st_port *port);
WORD sl_portH_getPortMode1(volatile st_port *port);
WORD sl_portH_getPortMode2(volatile st_port *port);
void sl_portH_setPortMode(volatile st_port *port, WORD mode);
void sl_portH_setPortMode1(volatile st_port *port, WORD mode);
void sl_portH_setPortMode2(volatile st_port *port, WORD mode);

int sl_portH_getPinMode(volatile st_port *port, BYTE pin);
void sl_portH_setPinMode(volatile st_port *port, BYTE pin, int mode);



#endif // __SL_PORT__H
